package com.lgmshare.k3.http.base;

import android.text.TextUtils;

import com.lgmshare.component.logger.Logger;
import com.lgmshare.component.network.HttpRequestClient;
import com.lgmshare.component.network.HttpResponseCallback;
import com.lgmshare.component.network.RequestHeaders;
import com.lgmshare.component.network.RequestParams;
import com.lgmshare.component.utils.EncryptUtils;
import com.lgmshare.component.utils.JSONUtils;
import com.lgmshare.component.utils.UIUtils;
import com.lgmshare.k3.K3Config;
import com.lgmshare.k3.http.HttpClientApi;
import com.lgmshare.k3.manager.UserInfoManager;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

/**
 * @author lim
 * @description: TODO
 * @email lgmshare@gmail.com
 * @datetime 2016/6/8 14:36
 */
public class SimpleTask<T> implements HttpResponseCallback {

    protected final String TAG = SimpleTask.this.getClass().getSimpleName();

    protected String mRequestUrl;
    protected RequestHeaders mRequestHeaders = new RequestHeaders();
    protected RequestParams mRequestParams = new RequestParams();

    protected SimpleCallback mCallback;

    /**
     * 构建请求URL
     *
     * @return
     */
    public String onCreateRequestUrl() {
        return TextUtils.isEmpty(mRequestUrl) ? HttpClientApi.BASE_URL : mRequestUrl;
    }

    public void setRequestUrl(String requestUrl) {
        mRequestUrl = requestUrl;
    }

    public void putHeaderParams(String key, String value) {
        mRequestHeaders.put(key, value);
    }

    public void putRequestParams(String key, String value) {
        mRequestParams.put(key, value);
    }

    /**
     * 回调方法
     *
     * @param callback
     */
    public void setRequestCallback(SimpleCallback<T> callback) {
        mCallback = callback;
    }

    /**
     * Post请求
     *
     * @param tag 请求TAG,使用上下文环境this,可实现activity（fragment）销毁自动取消请求
     */
    public void sendPost(Object tag) {
        RequestHeaders requestHeaders = buildHeaderParams();
        RequestParams requestParams = buildRequestParams();
        Logger.d(TAG, onCreateRequestUrl());
        Logger.d(TAG, requestParams.getParamString());
        HttpRequestClient.post(tag, onCreateRequestUrl(), requestParams, requestHeaders, this);
    }

    /**
     * Get请求
     *
     * @param tag 请求TAG,使用上下文环境this,可实现activity（fragment）销毁自动取消请求
     */
    public void sendGet(Object tag) {
        RequestHeaders requestHeaders = buildHeaderParams();
        RequestParams requestParams = buildRequestParams();
        Logger.d(TAG, onCreateRequestUrl());
        Logger.d(TAG, requestParams.getParamString());
        HttpRequestClient.get(tag, onCreateRequestUrl(), requestParams, requestHeaders, this);
    }

    /**
     * 构建公共Header参数
     *
     * @return
     */
    public RequestHeaders buildHeaderParams() {
        mRequestHeaders.put("User-Agent", Utils.getUserAgent());
        mRequestHeaders.put("Accept", HttpRequestClient.CONTENT_TYPE_JSON);
        mRequestHeaders.put("Content-Type", HttpRequestClient.CONTENT_TYPE_FORM);
        return mRequestHeaders;
    }

    /**
     * 构建公共请求参数
     *
     * @return
     */
    public RequestParams buildRequestParams() {
        UserInfoManager manager = UserInfoManager.getInstance();
        String timeMillis = String.valueOf(System.currentTimeMillis());
        String udid = manager.getUDID();
        String sign = udid + timeMillis + K3Config.INTERFACE_KEY;
        mRequestParams.put("IMEI", udid);
        mRequestParams.put("timestamp", timeMillis);
        mRequestParams.put("version", K3Config.INTERFACE_VERSION);
        mRequestParams.put("sign", EncryptUtils.encryptMD5ToString(sign));
        mRequestParams.put("site", K3Config.INTERFACE_SITE);
        mRequestParams.put("user_id", manager.getUserInfo() != null ? manager.getUserInfo().getUser_id() : "0");
        return mRequestParams;
    }

    @Override
    public void onStart() {
        UIUtils.runOnUiThread(() -> {
            if (mCallback != null) {
                mCallback.onStart();
            }
        });
    }

    @Override
    public void onCancel() {
        UIUtils.runOnUiThread(() -> {
            if (mCallback != null) {
                mCallback.onCancel();
            }
        });
    }

    @Override
    public void onFinish() {
        UIUtils.runOnUiThread(() -> {
            if (mCallback != null) {
                mCallback.onFinish();
            }
        });
    }

    @Override
    public void onProgress(long totalSize, long progress, long offset) {
        UIUtils.runOnUiThread(() -> {
            if (mCallback != null) {
                mCallback.onProgress(totalSize, progress, offset);
            }
        });
    }

    @Override
    public void onFailure(final int errorCode, final String errorMessage) {
        Logger.e(TAG, "errorCode=" + errorCode + "    errorMessage=" + errorMessage);
        String message;
        switch (errorCode) {
            case 200:
                message = "数据异常！";
                break;
            case 500:
                message = "服务器内部错误！";
                break;
            default:
                message = errorMessage;
                break;
        }
        handleFailure(errorCode, message);
    }

    @Override
    public void onSuccess(int statusCode, String responseBody) {
        Logger.d(TAG, "statusCode=" + statusCode + "   responseBody=" + responseBody);
        if (mCallback != null) {
            Type types = mCallback.getClass().getGenericSuperclass();
            Type type = ((ParameterizedType) types).getActualTypeArguments()[0];
            try {
                if (type instanceof Class && type.equals(StatusResult.class)) {
                    StatusResult result = JSONUtils.parseObject(responseBody, StatusResult.class);
                    if (result.isSuccess()) {
                        handleSuccess((T) result);
                    } else {
                        handleFailure(result.getCode(), result.getMessage());
                    }
                } else {
                    WrapperResult<T> result = JSONUtils.parseObject(responseBody, new ResultType(type));
                    if (result == null) {
                        handleFailure(-1, "response is null");
                        return;
                    }
                    if (result.isSuccess() && result.getData() != null) {
                        handleSuccess(result.getData());
                    } else {
                        handleFailure(result.getCode(), result.getMessage());
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
                handleFailure(-1, e.getMessage());
            }
        }
    }

    private void handleSuccess(T t) {
        UIUtils.runOnUiThread(() -> {
            if (mCallback != null) {
                mCallback.onSuccess(t);
            }
        });
    }

    private void handleFailure(int code, String message) {
        UIUtils.runOnUiThread(() -> {
            if (mCallback != null) {
                mCallback.onFailure(code, message);
            }
        });
    }

    private class ResultType implements ParameterizedType {
        private final Type type;

        public ResultType(Type type) {
            this.type = type;
        }

        @Override
        public Type[] getActualTypeArguments() {
            return new Type[]{type};
        }

        @Override
        public Type getOwnerType() {
            return null;
        }

        @Override
        public Type getRawType() {
            return WrapperResult.class;
        }
    }
}
